home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / parser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  24.8 KB  |  911 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains the Harvest C parser.  The parser is hand written.
  35.  * 
  36.  * 
  37.  */
  38.  
  39.  
  40. #include "conditcomp.h"
  41. #include <stdio.h>
  42. #include <string.h>
  43.  
  44. #include "structs.h"
  45.  
  46. #pragma segment Parser
  47.  
  48.  
  49. /* THEPARSER */
  50.  
  51. /*
  52.  * Parsing:  We conceptually separate parsing into 2 stages : syntactic
  53.  * parsing and semantic parsing.  During syntactic parsing, we wish to
  54.  * identify all problems occuring in syntax only - such as unmatched parens.
  55.  * During semantic parsing, we wish to identify all other problems which will
  56.  * prohibit us from producing assembler output.  These problems include : use
  57.  * of an undefined identifier, type mismatches, etc...
  58.  LastToken
  59.  */
  60. /*
  61.  * This compiler does not implement volatile.
  62.  */
  63.  
  64. /*
  65.  * Every routine which returns an expression, must set the type of that
  66.  * expression and whether or not it is an lvalue.  In fact, any such routine
  67.  * should have the following four items, for every call to BuildTree*().  1.
  68.  * The BuildTree*() call itself, 2.  Explicit setting of the type, 3.
  69.  * Explicit setting of the LValue status, and 4.  a TYPERULE comment,
  70.  * explaining what the rules behind that set were.  TYPERULE comments may
  71.  * also explain limitations on operands and the like.
  72.  */
  73.  
  74. ParseTreeVia_t
  75. Do_cast_expr(void)
  76. {
  77.     /*
  78.      * cast_expr : unary_expr | '(' type_name ')' cast_expr ;
  79.      */
  80.  
  81.     ParseTreeVia_t                  result;
  82.     result = NULL;
  83.     if (NextIs('(')) {
  84.     TypeRecordVia_t                 tmp;
  85.     tmp = Do_type_name();
  86.     if (tmp) {
  87.         if (!NextIs(')')) {
  88.         SyntaxError("Missing right parenthesis");
  89.         }
  90.         if (tmp) {
  91.         result = Do_cast_expr();
  92.         FuncPtrGenerate(&result);
  93.         if (result) {
  94.             if (SameType(tmp, GetTreeTP(result))) {
  95.             UserWarning(WARN_redundantcast);
  96.             }
  97.             result = TypeConvert(result, tmp);
  98.             CurrentSRC.CountCasts++;
  99.             Via(result)->LValue = 0;
  100.         } else {
  101.             SyntaxError("Expected expr after type cast");
  102.         }
  103.         } else {
  104.         SyntaxError("Expected type name for cast");
  105.         }
  106.     } else {
  107.         PutBackToken("(", '(');
  108.         result = NULL;
  109.     }
  110.     }
  111.     if (!result) {
  112.     result = Do_unary_expr();
  113.     }
  114.     return result;
  115. }
  116.  
  117. /*
  118.  * Here begin the arithmetic expressions.  Type checking for these is more
  119.  * complicated.  Every operand must be checked for valid type. Rules must be
  120.  * applied to ensure that the result type is correct. Handling of lvalue
  121.  * status is important.
  122.  */
  123.  
  124. ParseTreeVia_t
  125. Do_multiplicative_expr(void)
  126. {
  127.     /*
  128.      * multiplicative_expr : cast_expr | multiplicative_expr '*' cast_expr |
  129.      * multiplicative_expr '/' cast_expr | multiplicative_expr '%' cast_expr
  130.      * ;
  131.      */
  132.  
  133.     /*
  134.      * TYPERULE Both operands must be of arithmetic type.  The result type
  135.      * depends on the types of the operands.  For the % operator, both
  136.      * operands must be of integral type.
  137.      */
  138.     ParseTreeVia_t                  result;
  139.     TypeRecordVia_t                 resulttype;
  140.     ParseTreeVia_t                  right;
  141.     int                             donemulting;
  142.     result = Do_cast_expr();
  143.     if (result) {
  144.     donemulting = 0;
  145.     while (!donemulting) {
  146.         if (NextIs('*')) {
  147.         right = Do_cast_expr();
  148.         if (!isArithmeticType(GetTreeTP(result))) {
  149.             TypeError("* (multiplication) requires arithmetic type");
  150.         }
  151.         if (right) {
  152.             if (!isArithmeticType(GetTreeTP(right))) {
  153.             TypeError("* (multiplication) requires arithmetic type");
  154.             }
  155.             resulttype = Coerce(&result, &right, 0);
  156.             result = BuildTreeNode(PTF_multiply, result, right, NULL);
  157.             SetTreeTP(result, resulttype);
  158.             Via(result)->LValue = 0;
  159.         } else {
  160.             SyntaxError("Expected expr as rhs of * (multiplication)");
  161.         }
  162.         } else if (NextIs('/')) {
  163.         right = Do_cast_expr();
  164.         if (!isArithmeticType(GetTreeTP(result))) {
  165.             TypeError("/ requires arithmetic type");
  166.         }
  167.         if (right) {
  168.             if (!isArithmeticType(GetTreeTP(right))) {
  169.             TypeError("/ requires arithmetic type");
  170.             }
  171.             resulttype = Coerce(&result, &right, 0);
  172.             result = BuildTreeNode(PTF_divide, result, right, NULL);
  173.             SetTreeTP(result, resulttype);
  174.             Via(result)->LValue = 0;
  175.         } else {
  176.             SyntaxError("Expected expr as rhs of /");
  177.         }
  178.         } else if (NextIs('%')) {
  179.         right = Do_cast_expr();
  180.         if (!isIntegralType(GetTreeTP(result))) {
  181.             TypeError("% requires integral type");
  182.         }
  183.         if (right) {
  184.             if (!isIntegralType(GetTreeTP(right))) {
  185.             TypeError("% requires integral type");
  186.             }
  187.             resulttype = Coerce(&result, &right, 0);
  188.             result = BuildTreeNode(PTF_modulo, result, right, NULL);
  189.             SetTreeTP(result, resulttype);
  190.             Via(result)->LValue = 0;
  191.         } else {
  192.             SyntaxError("Expected expr as rhs of %");
  193.         }
  194.         } else {
  195.         donemulting = 1;
  196.         }
  197.     }
  198.     }
  199.     return result;
  200. }
  201.  
  202. ParseTreeVia_t
  203. Do_additive_expr(void)
  204. {
  205.     /*
  206.      * additive_expr : multiplicative_expr | additive_expr '+'
  207.      * multiplicative_expr | additive_expr '-' multiplicative_expr ;
  208.      */
  209.  
  210.     ParseTreeVia_t                  result;
  211.     TypeRecordVia_t                 resulttype;
  212.     ParseTreeVia_t                  tmp;
  213.     int                             doneadding;
  214.     result = Do_multiplicative_expr();
  215.     if (result) {
  216.     doneadding = 0;
  217.     while (!doneadding) {
  218.         if (NextIs('+')) {
  219.         tmp = Do_multiplicative_expr();
  220.         if (tmp) {
  221.             resulttype = Coerce(&result, &tmp, 0);
  222.             if (!isBooleanType(GetTreeTP(tmp))) {
  223.             TypeError("+ requires arithmetic or pointer type");
  224.             }
  225.             if (!isBooleanType(GetTreeTP(result))) {
  226.             TypeError("+ requires arithmetic or pointer type");
  227.             }
  228.             result = BuildTreeNode(PTF_add, result, tmp, NULL);
  229.             SetTreeTP(result, resulttype);
  230.             Via(result)->LValue = 0;
  231.         } else {
  232.             SyntaxError("Expected expr as rhs of +");
  233.         }
  234.         } else if (NextIs('-')) {
  235.         tmp = Do_multiplicative_expr();
  236.         if (!isBooleanType(GetTreeTP(result))) {
  237.             TypeError("- requires arithmetic or pointer type");
  238.         }
  239.         if (tmp) {
  240.             if (!isBooleanType(GetTreeTP(tmp))) {
  241.             TypeError("- requires arithmetic or pointer type");
  242.             }
  243.             resulttype = Coerce(&result, &tmp, 0);
  244.             if (isPointerType(GetTreeTP(result)) && isPointerType(GetTreeTP(tmp))) {
  245.             resulttype = BuildTypeRecord(0, TRC_long, SGN_signed);
  246.             }
  247.             result = BuildTreeNode(PTF_subtract, result, tmp, NULL);
  248.             SetTreeTP(result, resulttype);
  249.             Via(result)->LValue = 0;
  250.         } else {
  251.             SyntaxError("Expected expr as rhs of -");
  252.         }
  253.         } else {
  254.         doneadding = 1;
  255.         }
  256.     }
  257.     }
  258.     return result;
  259. }
  260.  
  261. ParseTreeVia_t
  262. Do_shift_expr(void)
  263. {
  264.     /*
  265.      * shift_expr : additive_expr | shift_expr LEFT_OP additive_expr |
  266.      * shift_expr RIGHT_OP additive_expr ;
  267.      */
  268.  
  269.     ParseTreeVia_t                  result;
  270.     TypeRecordVia_t                 resulttype;
  271.     ParseTreeVia_t                  tmp;
  272.     int                             doneshifting;
  273.     result = Do_additive_expr();
  274.     if (result) {
  275.     doneshifting = 0;
  276.     while (!doneshifting) {
  277.         if (NextIs(LEFT_OP)) {
  278.         if (!isIntegralType(GetTreeTP(result))) {
  279.             TypeError("<< requires integral type");
  280.         }
  281.         tmp = Do_additive_expr();
  282.         if (tmp) {
  283.             if (!isIntegralType(GetTreeTP(result))) {
  284.             TypeError("<< requires integral type");
  285.             }
  286.             resulttype = Coerce(&result, &tmp, 0);
  287.             result = BuildTreeNode(PTF_shift_left, result, tmp, NULL);
  288.             SetTreeTP(result, resulttype);
  289.             Via(result)->LValue = 0;
  290.         } else {
  291.             SyntaxError("Expected expr as rhs of <<");
  292.         }
  293.         } else if (NextIs(RIGHT_OP)) {
  294.         tmp = Do_additive_expr();
  295.         if (!isIntegralType(GetTreeTP(result))) {
  296.             TypeError(">> requires integral type");
  297.         }
  298.         if (tmp) {
  299.             if (!isIntegralType(GetTreeTP(result))) {
  300.             TypeError(">> requires integral type");
  301.             }
  302.             resulttype = Coerce(&result, &tmp, 0);
  303.             result = BuildTreeNode(PTF_shift_right, result, tmp, NULL);
  304.             SetTreeTP(result, resulttype);
  305.             Via(result)->LValue = 0;
  306.         } else {
  307.             SyntaxError("Expected expr as rhs of >>");
  308.         }
  309.         } else {
  310.         doneshifting = 1;
  311.         }
  312.     }
  313.     }
  314.     return result;
  315. }
  316.  
  317. ParseTreeVia_t
  318. Do_relational_expr(void)
  319. {
  320.     /*
  321.      * relational_expr : shift_expr | relational_expr '<' shift_expr |
  322.      * relational_expr '>' shift_expr | relational_expr LE_OP shift_expr |
  323.      * relational_expr GE_OP shift_expr ;
  324.      */
  325.  
  326.     ParseTreeVia_t                  result;
  327.     ParseTreeVia_t                  tmp;
  328.     int                             donerelating;
  329.     result = Do_shift_expr();
  330.     if (result) {
  331.     donerelating = 0;
  332.     while (!donerelating) {
  333.         if (NextIs('<')) {
  334.         tmp = Do_shift_expr();
  335.         if (!isBooleanType(GetTreeTP(result))) {
  336.             TypeError("< requires arithmetic or pointer type");
  337.         }
  338.         if (tmp) {
  339.             if (!isBooleanType(GetTreeTP(tmp))) {
  340.             TypeError("< requires arithmetic or pointer type");
  341.             }
  342.             RelateCoerce(&result, &tmp);
  343.             result = BuildTreeNode(PTF_lessthan, result, tmp, NULL);
  344.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  345.             Via(result)->LValue = 0;
  346.         } else {
  347.             SyntaxError("Expected expr as rhs of <");
  348.         }
  349.         } else if (NextIs('>')) {
  350.         tmp = Do_shift_expr();
  351.         if (!isBooleanType(GetTreeTP(result))) {
  352.             TypeError("> requires arithmetic or pointer type");
  353.         }
  354.         if (tmp) {
  355.             if (!isBooleanType(GetTreeTP(tmp))) {
  356.             TypeError("> requires arithmetic or pointer type");
  357.             }
  358.             RelateCoerce(&result, &tmp);
  359.             result = BuildTreeNode(PTF_greaterthan, result, tmp, NULL);
  360.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  361.             Via(result)->LValue = 0;
  362.         } else {
  363.             SyntaxError("Expected expr as rhs of >");
  364.         }
  365.         } else if (NextIs(LE_OP)) {
  366.         tmp = Do_shift_expr();
  367.         if (!isBooleanType(GetTreeTP(result))) {
  368.             TypeError("<= requires arithmetic or pointer type");
  369.         }
  370.         if (tmp) {
  371.             if (!isBooleanType(GetTreeTP(tmp))) {
  372.             TypeError("<= requires arithmetic or pointer type");
  373.             }
  374.             RelateCoerce(&result, &tmp);
  375.             result = BuildTreeNode(PTF_lessthaneq, result, tmp, NULL);
  376.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  377.             Via(result)->LValue = 0;
  378.         } else {
  379.             SyntaxError("Expected expr as rhs of <=");
  380.         }
  381.         } else if (NextIs(GE_OP)) {
  382.         tmp = Do_shift_expr();
  383.         if (!isBooleanType(GetTreeTP(result))) {
  384.             TypeError(">= requires arithmetic or pointer type");
  385.         }
  386.         if (tmp) {
  387.             if (!isBooleanType(GetTreeTP(tmp))) {
  388.             TypeError(">= requires arithmetic or pointer type");
  389.             }
  390.             RelateCoerce(&result, &tmp);
  391.             result = BuildTreeNode(PTF_greaterthaneq, result, tmp, NULL);
  392.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  393.             Via(result)->LValue = 0;
  394.         } else {
  395.             SyntaxError("Expected expr as rhs of >=");
  396.         }
  397.         } else {
  398.         donerelating = 1;
  399.         }
  400.     }
  401.     }
  402.     return result;
  403. }
  404.  
  405. ParseTreeVia_t
  406. Do_equality_expr(void)
  407. {
  408.     /*
  409.      * equality_expr : relational_expr | equality_expr EQ_OP relational_expr
  410.      * | equality_expr NE_OP relational_expr ;
  411.      */
  412.  
  413.     ParseTreeVia_t                  result;
  414.     ParseTreeVia_t                  tmp;
  415.     result = Do_relational_expr();
  416.     if (result) {
  417.     if (NextIs(EQ_OP)) {
  418.         tmp = Do_relational_expr();
  419.         if (!isBooleanType(GetTreeTP(result))) {
  420.         TypeError("== requires arithmetic or pointer type");
  421.         }
  422.         if (tmp) {
  423.         if (!isBooleanType(GetTreeTP(tmp))) {
  424.             TypeError("== requires arithmetic or pointer type");
  425.         }
  426.         (void) Coerce(&result, &tmp, 0);
  427.         if (isFloatingType(GetTreeTP(result))) {
  428.             UserWarning(WARN_floateqcompare);
  429.         }
  430.         result = BuildTreeNode(PTF_equal, result, tmp, NULL);
  431.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  432.         Via(result)->LValue = 0;
  433.         } else {
  434.         SyntaxError("Expected expr as rhs of ==");
  435.         }
  436.     } else if (NextIs(NE_OP)) {
  437.         tmp = Do_relational_expr();
  438.         if (!isBooleanType(GetTreeTP(result))) {
  439.         TypeError("!= requires arithmetic or pointer type");
  440.         }
  441.         if (tmp) {
  442.         if (!isBooleanType(GetTreeTP(tmp))) {
  443.             TypeError("!= requires arithmetic or pointer type");
  444.         }
  445.         (void) Coerce(&result, &tmp, 0);
  446.         if (isFloatingType(GetTreeTP(result))) {
  447.             UserWarning(WARN_floateqcompare);
  448.         }
  449.         result = BuildTreeNode(PTF_notequal, result, tmp, NULL);
  450.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  451.         Via(result)->LValue = 0;
  452.         } else {
  453.         SyntaxError("Expected expr as rhs of !=");
  454.         }
  455.     }
  456.     }
  457.     return result;
  458. }
  459.  
  460. ParseTreeVia_t
  461. Do_and_expr(void)
  462. {
  463.     /*
  464.      * and_expr : equality_expr | and_expr '&' equality_expr ;
  465.      */
  466.  
  467.     ParseTreeVia_t                  result;
  468.     TypeRecordVia_t                 resulttype;
  469.     ParseTreeVia_t                  tmp;
  470.     int                             doneanding;
  471.     result = Do_equality_expr();
  472.     if (result) {
  473.     doneanding = 0;
  474.     while (!doneanding) {
  475.         if (NextIs('&')) {
  476.         tmp = Do_equality_expr();
  477.         if (!isIntegralType(GetTreeTP(result))) {
  478.             TypeError("& (bitwise and) requires integral type");
  479.         }
  480.         if (tmp) {
  481.             if (!isIntegralType(GetTreeTP(tmp))) {
  482.             TypeError("& (bitwise and) requires integral type");
  483.             }
  484.             resulttype = Coerce(&result, &tmp, 0);
  485.             result = BuildTreeNode(PTF_bitwise_and, result, tmp, NULL);
  486.             SetTreeTP(result, resulttype);
  487.             Via(result)->LValue = 0;
  488.         } else {
  489.             SyntaxError("Expected expr as rhs of &");
  490.         }
  491.         } else {
  492.         doneanding = 1;
  493.         }
  494.     }
  495.     }
  496.     return result;
  497. }
  498.  
  499. ParseTreeVia_t
  500. Do_exclusive_or_expr(void)
  501. {
  502.     /*
  503.      * exclusive_or_expr : and_expr | exclusive_or_expr '^' and_expr ;
  504.      */
  505.  
  506.     ParseTreeVia_t                  result;
  507.     TypeRecordVia_t                 resulttype;
  508.     ParseTreeVia_t                  tmp;
  509.     int                             doneexoring;
  510.     result = Do_and_expr();
  511.     if (result) {
  512.     doneexoring = 0;
  513.     while (!doneexoring) {
  514.         if (NextIs('^')) {
  515.         tmp = Do_and_expr();
  516.         if (!isIntegralType(GetTreeTP(result))) {
  517.             TypeError("^ requires integral type");
  518.         }
  519.         if (tmp) {
  520.             if (!isIntegralType(GetTreeTP(tmp))) {
  521.             TypeError("^ requires integral type");
  522.             }
  523.             resulttype = Coerce(&result, &tmp, 0);
  524.             result = BuildTreeNode(PTF_bitwise_xor, result, tmp, NULL);
  525.             SetTreeTP(result, resulttype);
  526.             Via(result)->LValue = 0;
  527.         } else {
  528.             SyntaxError("Expected expr as rhs of ^");
  529.         }
  530.         } else {
  531.         doneexoring = 1;
  532.         }
  533.     }
  534.     }
  535.     return result;
  536. }
  537.  
  538. ParseTreeVia_t
  539. Do_inclusive_or_expr(void)
  540. {
  541.     /*
  542.      * inclusive_or_expr : exclusive_or_expr | inclusive_or_expr '|'
  543.      * exclusive_or_expr ;
  544.      */
  545.  
  546.     ParseTreeVia_t                  result;
  547.     TypeRecordVia_t                 resulttype;
  548.     ParseTreeVia_t                  tmp;
  549.     int                             doneinoring;
  550.     result = Do_exclusive_or_expr();
  551.     if (result) {
  552.     doneinoring = 0;
  553.     while (!doneinoring) {
  554.         if (NextIs('|')) {
  555.         tmp = Do_exclusive_or_expr();
  556.         if (!isIntegralType(GetTreeTP(result))) {
  557.             TypeError("| requires integral type");
  558.         }
  559.         if (tmp) {
  560.             if (!isIntegralType(GetTreeTP(tmp))) {
  561.             TypeError("| requires integral type");
  562.             }
  563.             resulttype = Coerce(&result, &tmp, 0);
  564.             result = BuildTreeNode(PTF_bitwise_or, result, tmp, NULL);
  565.             SetTreeTP(result, resulttype);
  566.             Via(result)->LValue = 0;
  567.         } else {
  568.             SyntaxError("Expected expr as rhs of |");
  569.         }
  570.         } else {
  571.         doneinoring = 1;
  572.         }
  573.     }
  574.     }
  575.     return result;
  576. }
  577.  
  578. ParseTreeVia_t
  579. Do_logical_and_expr(void)
  580. {
  581.     /*
  582.      * logical_and_expr : inclusive_or_expr | logical_and_expr AND_OP
  583.      * inclusive_or_expr ;
  584.      */
  585.  
  586.     ParseTreeVia_t                  result;
  587.     ParseTreeVia_t                  tmp;
  588.     int                             donelogicaland;
  589.     result = Do_inclusive_or_expr();
  590.     if (result) {
  591.     donelogicaland = 0;
  592.     while (!donelogicaland) {
  593.         if (NextIs(AND_OP)) {
  594.         tmp = Do_inclusive_or_expr();
  595.         if (!isBooleanType(GetTreeTP(result))) {
  596.             TypeError("&& requires arithmetic or pointer type");
  597.         }
  598.         if (tmp) {
  599.             if (!isBooleanType(GetTreeTP(tmp))) {
  600.             TypeError("&& requires arithmetic or pointer type");
  601.             }
  602.             /* QQQQ Can I really delete this ? */
  603. #ifdef UNDEFINED
  604.             (void) Coerce(&result, &tmp, 1);
  605. #endif
  606.             result = BuildTreeNode(PTF_logical_and, result, tmp, NULL);
  607.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  608.             Via(result)->LValue = 0;
  609.         } else {
  610.             SyntaxError("Expected expr as rhs of &&");
  611.         }
  612.         } else {
  613.         donelogicaland = 1;
  614.         }
  615.     }
  616.     }
  617.     return result;
  618. }
  619.  
  620. ParseTreeVia_t
  621. Do_logical_or_expr(void)
  622. {
  623.     /*
  624.      * logical_or_expr : logical_and_expr | logical_or_expr OR_OP
  625.      * logical_and_expr ;
  626.      */
  627.  
  628.     ParseTreeVia_t                  result;
  629.     ParseTreeVia_t                  tmp;
  630.     int                             donelogicalor;
  631.     result = Do_logical_and_expr();
  632.     if (result) {
  633.     donelogicalor = 0;
  634.     while (!donelogicalor) {
  635.         if (NextIs(OR_OP)) {
  636.         tmp = Do_logical_and_expr();
  637.         if (!isBooleanType(GetTreeTP(result))) {
  638.             TypeError("|| requires arithmetic or pointer type");
  639.         }
  640.         if (tmp) {
  641.             if (!isBooleanType(GetTreeTP(tmp))) {
  642.             TypeError("|| requires arithmetic or pointer type");
  643.             }
  644.             /* QQQQ Can I really delete this ? */
  645. #ifdef UNDEFINED
  646.             (void) Coerce(&result, &tmp, 1);
  647. #endif
  648.             result = BuildTreeNode(PTF_logical_or, result, tmp, NULL);
  649.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  650.             Via(result)->LValue = 0;
  651.         } else {
  652.             SyntaxError("Expected expr as rhs of ||");
  653.         }
  654.         } else {
  655.         donelogicalor = 1;
  656.         }
  657.     }
  658.     }
  659.     return result;
  660. }
  661.  
  662. ParseTreeVia_t
  663. Do_conditional_expr(void)
  664. {
  665.     /*
  666.      * conditional_expr : logical_or_expr | logical_or_expr '?'
  667.      * logical_or_expr ':' conditional_expr ;
  668.      */
  669.  
  670.     ParseTreeVia_t                  result;
  671.     TypeRecordVia_t                 resulttype;
  672.     ParseTreeVia_t                  tmp2;
  673.     result = Do_logical_or_expr();
  674.     if (result) {
  675.     if (NextIs('?')) {
  676.         ParseTreeVia_t                  tmp;
  677.         tmp = Do_logical_or_expr();
  678.         if (!isBooleanType(GetTreeTP(result))) {
  679.         TypeError("Left operand of ? operator must be arithmetic or pointer");
  680.         }
  681.         if (tmp) {
  682.         if (NextIs(':')) {
  683.             tmp2 = Do_conditional_expr();
  684.             if (tmp2) {
  685.             resulttype = Coerce(&tmp, &tmp2, 0);
  686.             if (!SameType(GetTreeTP(tmp), GetTreeTP(tmp2))) {
  687.                 TypeError("Middle and rightmost operands of ?: must be of same type.");
  688.             }
  689.             result = BuildTreeNode(PTF_ternary, result, tmp, tmp2);
  690.             SetTreeTP(result, resulttype);
  691.             Via(result)->LValue = 0;
  692.             } else {
  693.             SyntaxError("Expected 3rd expr for ternary");
  694.             }
  695.         } else {
  696.             SyntaxError("Expected : following ?");
  697.         }
  698.         } else {
  699.         SyntaxError("Expected middle expr for ternary");
  700.         }
  701.     }
  702.     }
  703.     return result;
  704. }
  705.  
  706. ParseTreeVia_t
  707. Do_assignment_expr(void)
  708. {
  709.     /*
  710.      * assignment_expr : conditional_expr | unary_expr assignment_operator
  711.      * assignment_expr ;
  712.      */
  713.     /*
  714.      * This routine is the parser to call for reading an expression where
  715.      * commas are not legal (such as in function arguments).
  716.      */
  717.     ParseTreeVia_t                  result;
  718.     Codigo_t                        tmp;
  719.     ParseTreeVia_t                  tmp2;
  720.  
  721.     result = Do_conditional_expr();
  722.     if (result) {
  723.     PtrGenerate(&result);
  724.     tmp = Do_assignment_operator();
  725.     if (tmp) {
  726.         if (!Via(result)->LValue) {
  727.         SemanticError("Assignment requires an lvalue on left");
  728.         }
  729.         if (GetTPQual(GetTreeTP(result)) == SCC_const) {
  730.         SemanticError("No assignment to const types");
  731.         }
  732.         tmp2 = Do_assignment_expr();
  733.         if (tmp2) {
  734.         (void) AssignCoerce(&result, &tmp2);
  735.         if (!SameType(GetTreeTP(result), GetTreeTP(tmp2))) {
  736.             TypeError("Incompatible types for assignment");
  737.         }
  738.         switch (tmp) {
  739.         case '=':
  740.             result = BuildTreeNode(PTF_assign, result, tmp2, NULL);
  741.             SetTreeTP(result, GetTreeTP(tmp2));
  742.             Via(result)->LValue = 0;
  743.             break;
  744.         case MUL_ASSIGN:
  745.             result = BuildTreeNode(PTF_mulassign, result, tmp2, NULL);
  746.             SetTreeTP(result, GetTreeTP(tmp2));
  747.             Via(result)->LValue = 0;
  748.             break;
  749.         case DIV_ASSIGN:
  750.             result = BuildTreeNode(PTF_divassign, result, tmp2, NULL);
  751.             SetTreeTP(result, GetTreeTP(tmp2));
  752.             Via(result)->LValue = 0;
  753.             break;
  754.         case MOD_ASSIGN:
  755.             if (isFloatingType(GetTreeTP(result))) {
  756.             TypeError("%= requires integral type");
  757.             }
  758.             result = BuildTreeNode(PTF_modassign, result, tmp2, NULL);
  759.             SetTreeTP(result, GetTreeTP(tmp2));
  760.             Via(result)->LValue = 0;
  761.             break;
  762.         case ADD_ASSIGN:
  763.             result = BuildTreeNode(PTF_addassign, result, tmp2, NULL);
  764.             SetTreeTP(result, GetTreeTP(tmp2));
  765.             Via(result)->LValue = 0;
  766.             break;
  767.         case SUB_ASSIGN:
  768.             result = BuildTreeNode(PTF_subassign, result, tmp2, NULL);
  769.             SetTreeTP(result, GetTreeTP(tmp2));
  770.             Via(result)->LValue = 0;
  771.             break;
  772.         case LEFT_ASSIGN:
  773.             if (isFloatingType(GetTreeTP(result))) {
  774.             TypeError("<<= requires integral type");
  775.             }
  776.             result = BuildTreeNode(PTF_leftassign, result, tmp2, NULL);
  777.             SetTreeTP(result, GetTreeTP(tmp2));
  778.             Via(result)->LValue = 0;
  779.             break;
  780.         case RIGHT_ASSIGN:
  781.             if (isFloatingType(GetTreeTP(result))) {
  782.             TypeError(">>= requires integral type");
  783.             }
  784.             result = BuildTreeNode(PTF_rightassign, result, tmp2, NULL);
  785.             SetTreeTP(result, GetTreeTP(tmp2));
  786.             Via(result)->LValue = 0;
  787.             break;
  788.         case AND_ASSIGN:
  789.             if (isFloatingType(GetTreeTP(result))) {
  790.             TypeError("&= requires integral type");
  791.             }
  792.             result = BuildTreeNode(PTF_andassign, result, tmp2, NULL);
  793.             SetTreeTP(result, GetTreeTP(tmp2));
  794.             Via(result)->LValue = 0;
  795.             break;
  796.         case XOR_ASSIGN:
  797.             if (isFloatingType(GetTreeTP(result))) {
  798.             TypeError("^= requires integral type");
  799.             }
  800.             result = BuildTreeNode(PTF_xorassign, result, tmp2, NULL);
  801.             SetTreeTP(result, GetTreeTP(tmp2));
  802.             Via(result)->LValue = 0;
  803.             break;
  804.         case OR_ASSIGN:
  805.             if (isFloatingType(GetTreeTP(result))) {
  806.             TypeError("|= requires integral type");
  807.             }
  808.             result = BuildTreeNode(PTF_orassign, result, tmp2, NULL);
  809.             SetTreeTP(result, GetTreeTP(tmp2));
  810.             Via(result)->LValue = 0;
  811.             break;
  812.         default:
  813.             break;
  814.         }
  815.         } else {
  816.         SyntaxError("Expected expr for rhs of = (assignment)");
  817.         }
  818.     }
  819.     }
  820.     return result;
  821. }
  822.  
  823. Codigo_t
  824. Do_assignment_operator(void)
  825. {
  826.     /*
  827.      * assignment_operator : '=' | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN |
  828.      * ADD_ASSIGN | SUB_ASSIGN | LEFT_ASSIGN | RIGHT_ASSIGN | AND_ASSIGN |
  829.      * XOR_ASSIGN | OR_ASSIGN ;
  830.      */
  831.  
  832.     if (NextIs('=')) {
  833.     return '=';
  834.     } else if (NextIs(MUL_ASSIGN)) {
  835.     return MUL_ASSIGN;
  836.     } else if (NextIs(DIV_ASSIGN)) {
  837.     return DIV_ASSIGN;
  838.     } else if (NextIs(MOD_ASSIGN)) {
  839.     return MOD_ASSIGN;
  840.     } else if (NextIs(ADD_ASSIGN)) {
  841.     return ADD_ASSIGN;
  842.     } else if (NextIs(SUB_ASSIGN)) {
  843.     return SUB_ASSIGN;
  844.     } else if (NextIs(LEFT_ASSIGN)) {
  845.     return LEFT_ASSIGN;
  846.     } else if (NextIs(RIGHT_ASSIGN)) {
  847.     return RIGHT_ASSIGN;
  848.     } else if (NextIs(AND_ASSIGN)) {
  849.     return AND_ASSIGN;
  850.     } else if (NextIs(XOR_ASSIGN)) {
  851.     return XOR_ASSIGN;
  852.     } else if (NextIs(OR_ASSIGN)) {
  853.     return OR_ASSIGN;
  854.     } else {
  855.     return 0;
  856.     }
  857. }
  858.  
  859. ParseTreeVia_t
  860. Do_expr(void)
  861. {
  862.     /*
  863.      * expr : assignment_expr | expr ',' assignment_expr ;
  864.      */
  865.     /*
  866.      * This is the parser routine to call for reading an expression. It
  867.      * returns an expression parse tree.  The expression parsed should be one
  868.      * wherein commas are legal.
  869.      */
  870.  
  871.     ParseTreeVia_t                  result;
  872.     ParseTreeVia_t                  tmp;
  873.     int                             doneexpring;
  874.     result = Do_assignment_expr();
  875.     if (result) {
  876.     doneexpring = 0;
  877.     while (!doneexpring) {
  878.         if (NextIs(',')) {
  879.         tmp = Do_assignment_expr();
  880.         if (tmp) {
  881.             result = BuildTreeNode(PTF_commas, result, tmp, NULL);
  882.             SetTreeTP(result, GetTreeTP(tmp));
  883.             Via(result)->LValue = 0;
  884.         } else {
  885.             SyntaxError("Expected expr following comma");
  886.         }
  887.         } else {
  888.         doneexpring = 1;
  889.         }
  890.     }
  891.     }
  892.     return result;
  893. }
  894.  
  895. ParseTreeVia_t
  896. Do_constant_expr(void)
  897. {
  898.     /*
  899.      * constant_expr : conditional_expr ;
  900.      */
  901.     /*
  902.      * There are semantic restrictions as to what may appear in a constant
  903.      * expression.  They will be verified using the is_constant field of the
  904.      * expr struct.
  905.      */
  906.  
  907.     ParseTreeVia_t                  result;
  908.     result = Do_conditional_expr();
  909.     return result;
  910. }
  911.